package com.gps.gate.handler;


import com.alibaba.fastjson.JSONObject;
import com.gps.common.Constants;
import com.gps.common.MessageType;
import com.gps.common.cache.CacheKeys;
import com.gps.common.model.BaseModel;
import com.gps.common.model.Command;
import com.gps.common.model.CommandResult;
import com.gps.common.model.Position;
import com.gps.gate.database.ActiveDevice;
import com.gps.gate.database.CommandsManager;
import com.gps.gate.database.ConnectionManager;
import com.gps.gate.trans.PosTrans;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Date;
import java.util.List;

@Component
//@Scope("prototype")
@ChannelHandler.Sharable
public class MainDataHandler extends ChannelInboundHandlerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(MainDataHandler.class);

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private PosTrans posTrans;

    @Autowired
    private ConnectionManager connectionManager;

    @Autowired
    private CommandsManager commandsManager;

    public MainDataHandler() {
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object decodedMessage) throws Exception {
        if (decodedMessage != null) {
            BaseModel baseModel = new BaseModel();
            baseModel.setServerTime(new Date());
            if (decodedMessage instanceof Position) {
                Position position = (Position) decodedMessage;
                baseModel.setImei(position.getImei());
                baseModel.setMessageType(MessageType.TYPE_POSITIONS);
                baseModel.setPosition(position);
                pushMessage(baseModel);
            } else if (decodedMessage instanceof Collection) {
                List<Position> positions = (List) decodedMessage;
                if (positions.size() > 0) {
                    baseModel.setImei(positions.get(0).getImei());
                    baseModel.setMessageType(MessageType.TYPE_POSITIONS);
                    baseModel.setPositions(positions);

                    pushMessage(baseModel);
                }
            } else if (decodedMessage instanceof CommandResult) {
                CommandResult commandResult = (CommandResult) decodedMessage;
                //取出缓存中需要响应的命令
                String cmdKey = CacheKeys.getFeedbackKeys(commandResult.getImei(),commandResult.getCommandFlowId());
                System.out.println("get response Command where key is: " + cmdKey);

                String resultCommand = stringRedisTemplate.opsForValue().get(cmdKey);
                LOGGER.info(">>>>>>>>>>>>>>>>>>>>get response Command: " + resultCommand);
                if (!StringUtils.isEmpty(resultCommand)) {
                    Command command = JSONObject.parseObject(resultCommand, Command.class);
                    //移除用户命令
                    String commandKeys = CacheKeys.getCommandKeys(command.getType(), commandResult.getImei());
                    stringRedisTemplate.delete(commandKeys);
                    //移除已响应的缓存命令
                    stringRedisTemplate.delete(CacheKeys.getFeedbackKeys(commandResult.getImei(), commandResult.getCommandFlowId()));
                    commandResult.setType(command.getType());
                    commandResult.setUserId(command.getString(Constants.USER_ID));
                    commandResult.setCommandLogId(command.getString(Constants.COMMAND_LOG_ID));        //下发命令唯一标识 对应MySQL id
                    commandResult.setUserPhone(command.getString(Constants.USER_PHONE));
                    commandResult.setPlatform(command.getString(Constants.PLATFORM));
                }
                baseModel.setImei(commandResult.getImei());
                baseModel.setMessageType(MessageType.TYPE_RESULTS);
                baseModel.setCommandResult(commandResult);

                pushMessage(baseModel);
                return;
            } else if (decodedMessage instanceof BaseModel) {
                BaseModel model = (BaseModel) decodedMessage;
                pushMessage(model);
                return;
            }
            if (decodedMessage instanceof Collection) {
                for (Object o : (Collection) decodedMessage) {
                    ctx.fireChannelRead(o);
                }
            } else {
                ctx.fireChannelRead(decodedMessage);
            }
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //连接断开
        ActiveDevice activeDevice = connectionManager.removeActiveDevice(ctx.channel());
        if (activeDevice != null) {
            BaseModel baseModel = new BaseModel();
            baseModel.setImei(activeDevice.getImei());
            baseModel.setServerTime(new Date());
            baseModel.setMessageType(MessageType.TYPE_OFFLINE);
            pushMessage(baseModel);
        }
        super.channelInactive(ctx);
    }

    public void pushMessage(BaseModel model) {
        String message = JSONObject.toJSONString(model);
        LOGGER.info(message);
        posTrans.send(model);
    }
}
